#region  == Copyright == 
// =====================================================================
//  Microsoft Consulting Services France - Aymeric Mouillé - 2013
//  Projet     : Solution Cmd Helper - Solution Cmd Helper
//  Fichier    : ConsoleHelper.cs (24/06/2013 20:50)
//  
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// =====================================================================
#endregion

namespace Solution.Cmd.Helper
{
    #region  == Using == 
    using System;

    #endregion

    public class ConsoleHelper
    {
        /// <summary>
        /// </summary>
        private const int CONSOLE_WIDTH = 150;

        #region Ask For Continue
        /// <summary>
        /// Asks for continue.
        /// </summary>
        /// <returns></returns>
        public static bool AskForContinue()
        {
            Console.WriteLine("Do you want to continue? (Enter, space, y or 1 to continue)");
            SetConsoleSize();
            var result = Console.ReadKey();
            Console.WriteLine();
            if (result.Key == ConsoleKey.Y)
            {
                return true;
            }
            if (result.Key == ConsoleKey.Enter)
            {
                return true;
            }
            if (result.Key == ConsoleKey.Spacebar)
            {
                return true;
            }
            if (result.Key == ConsoleKey.NumPad1)
            {
                return true;
            }
            return false;
        }
        #endregion

        #region Ask For Retry
        /// <summary>
        /// Asks for retry.
        /// </summary>
        /// <returns></returns>
        public static bool AskForRetry()
        {
            Console.WriteLine("Retry (r) or abort (a) ?");
            SetConsoleSize();
            var result = Console.ReadKey();
            Console.WriteLine();
            if (result.Key == ConsoleKey.A)
            {
                return false;
            }
            if (result.Key == ConsoleKey.R)
            {
                return true;
            }
            return false;
        }
        #endregion

        #region Display Summary
        /// <summary>
        /// Displays the summary.
        /// </summary>
        /// <param name="title">The title.</param>
        /// <param name="desc">The desc.</param>
        public static void DisplaySummary(string title, string desc)
        {
            Console.Title = title;
            WriteFullLine('=', ConsoleColor.Gray);
            WriteCenter(title, ConsoleColor.White);
            WriteFullLine('=', ConsoleColor.Gray);

            Console.WriteLine(desc);
            Console.WriteLine();
        }
        #endregion

        #region End
        /// <summary>
        /// Wait key to close the console window
        /// </summary>
        /// <returns></returns>
        public static void End()
        {
            Console.WriteLine();
            Console.WriteLine("Press a key to close this window");
            Console.Title = "Completed";
            Console.Read();
        }
        #endregion

        #region Render Console Progress
        /// <summary>
        /// Renders the console progress.
        /// </summary>
        /// <param name="percentage">The percentage.</param>
        /// <param name="progressBarCharacter">The progress bar character.</param>
        /// <param name="color">The color.</param>
        /// <param name="message">The message.</param>
        public static void RenderConsoleProgress(int percentage, string message)
        {
            Console.CursorVisible = false;
            ConsoleColor originalColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.CursorLeft = 0;
            int width = Console.WindowWidth - 1;
            int newWidth = (int)((width * percentage) / 100d);
            string progBar = new string('\u2592', newWidth) + new string(' ', width - newWidth);
            Console.Write(progBar);
            if (string.IsNullOrEmpty(message))
            {
                message = string.Empty;
            }
            Console.CursorTop++;
            OverwriteConsoleMessage(message);
            Console.CursorTop--;
            Console.ForegroundColor = originalColor;
            Console.CursorVisible = true;
        }
        #endregion

        #region Set Console Size
        /// <summary>
        /// Sets the size of the console.
        /// </summary>
        public static void SetConsoleSize()
        {
            try
            {
                Console.WindowHeight = 55;
                Console.WindowWidth = CONSOLE_WIDTH;
                Console.BufferHeight = 9999;
            }
            catch (Exception)
            {
                // Ignore
            }
        }
        #endregion

        #region Write
        /// <summary>
        /// Writes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="color">The color.</param>
        public static void Write(string message, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.Write(message);
            Console.ForegroundColor = ConsoleColor.White;
        }
        #endregion

        #region Write Error
        /// <summary>
        /// Writes the error.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void WriteError(string message)
        {
            WriteLine(message, ConsoleColor.Red);
        }
        #endregion

        #region Write Warning
        /// <summary>
        /// Writes the warning.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void WriteWarning(string message)
        {
            WriteLine(message, ConsoleColor.Yellow);
        }
        #endregion

        #region Write Success
        /// <summary>
        /// Writes the success.
        /// </summary>
        /// <param name="message">The message.</param>
        public static void WriteSuccess(string message)
        {
            WriteLine(message, ConsoleColor.Green);
        }
        #endregion

        #region Write Center
        /// <summary>
        /// Writes the center.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="color">The color.</param>
        public static void WriteCenter(string message, ConsoleColor color)
        {
            int padLeft = (CONSOLE_WIDTH - message.Length) / 2;

            Console.ForegroundColor = color;
            Console.WriteLine(message.PadLeft(message.Length + padLeft, ' '));
            Console.ForegroundColor = ConsoleColor.White;
        }
        #endregion

        #region Write Full Line
        /// <summary>
        /// Writes the full line.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="color">The color.</param>
        public static void WriteFullLine(char value, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(string.Empty.PadLeft(CONSOLE_WIDTH - 1, value));
            Console.ForegroundColor = ConsoleColor.White;
        }
        #endregion

        #region Write Line
        /// <summary>
        /// Writes the line.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="color">The color.</param>
        public static void WriteLine(string message, ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(message);
            Console.ForegroundColor = ConsoleColor.White;
        }

        /// <summary>
        /// Writes the line.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="color">The color.</param>
        /// <param name="args"></param>
        public static void WriteLine(string message, ConsoleColor color, params object[] args)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(message, args);
            Console.ForegroundColor = ConsoleColor.White;
        }
        #endregion

        #region Write Separator
        /// <summary>
        /// Writes the separator.
        /// </summary>
        public static void WriteSeparator()
        {
            WriteFullLine('=', ConsoleColor.Cyan);
            Console.WriteLine();
        }
        #endregion

        #region Write Underlined Message
        /// <summary>
        /// Writes the underlined message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="color">The color.</param>
        /// <param name="underlineAllWidth">
        /// if set to <c>true</c> [underline all width].
        /// </param>
        public static void WriteUnderlinedMessage(string message, ConsoleColor color, bool underlineAllWidth)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(message);

            if (underlineAllWidth)
            {
                WriteFullLine('-', color);
            }
            else
            {
                Console.WriteLine(string.Empty.PadLeft(message.Length, '-'));
            }

            Console.ForegroundColor = ConsoleColor.White;
        }
        #endregion

        #region Overwrite Console Message
        /// <summary>
        /// Overwrites the console message.
        /// </summary>
        /// <param name="message">The message.</param>
        private static void OverwriteConsoleMessage(string message)
        {
            Console.CursorLeft = 0;
            int maxCharacterWidth = Console.WindowWidth - 1;
            if (message.Length > maxCharacterWidth)
            {
                message = string.Format("{0}...", message.Substring(0, maxCharacterWidth - 3));
            }
            message = string.Format("{0}{1}", message, new string(' ', maxCharacterWidth - message.Length));
            Console.Write(message);
        }
        #endregion
    }
}
